package com.colorlight.cloud.gateway.api.message.interceptor.trans.impl;

import com.colorlight.cloud.gateway.api.exception.ReflexException;
import com.colorlight.cloud.gateway.api.message.constraint.basics.ienum.EnumTrans;
import com.colorlight.cloud.gateway.api.message.interceptor.trans.TransToProtoInterceptor;
import com.colorlight.cloud.gateway.api.message.utils.BaseType;
import com.google.protobuf.Message;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.*;
import java.util.Objects;

/**
 * 枚举类型 过滤转化 配合{@link EnumTrans}使用 继承这个类型的枚举才可以使用
 *
 * @author Demon
 * @date 19/12/2023  下午3:13
 */
@Slf4j
public class EnumTransToProtoInterceptor implements TransToProtoInterceptor {
	@Override
	public Boolean isInterceptor(Class<?> aClass) {
		/**
		 * 枚举类型 且实现接口才可以被转化
		 */
		return Enum.class.isAssignableFrom(aClass) && EnumTrans.class.isAssignableFrom(aClass);
	}
	
	/**
	 * 1.构建对象
	 * 2.
	 */
	
	
	@Override
	public void addAttribute(Message.Builder builder, Object value, Class<?> inputClass, String methodName) {
		//  inputClass 封装数据数据类型 需要转为基本类型
		EnumTrans<?, ?> enumTrans = (EnumTrans<?, ?>) value;
		Object objectToProto = enumTrans.toProto();
		Method method = null;
		try {
			method = builder.getClass().getMethod(methodName, inputClass);
		} catch (NoSuchMethodException e) {
			log.error("", e);
		}
		if (method == null) {
			throw new ReflexException("获取方法失败");
		}
		// 方法调用
		try {
			method.invoke(builder, objectToProto);
		} catch (IllegalAccessException | InvocationTargetException e) {
			log.error("", e);
		}
	}
	
	@Override
	public Class<?> getInputClass(Field field) {
		Class<?> aClass = enumTransInternalType(field.getType());
		//基本数据类型过滤 入参可能是基本类型 单个赋值需要从封装数据类型转为基本类型
		if (BaseType.isContains(aClass)) {
			return BaseType.convert(aClass);
		}
		return aClass;
	}
	
	
	/**
	 * EnumTrans 类的处理
	 *
	 * @param aClass 实现类
	 * @return 目标类型集合得内置类型 单层集合
	 * @author Demon
	 * @date 18/12/2023/下午2:34
	 */
	private Class<?> enumTransInternalType(Class<?> aClass) {
		Type[] interfaceTypes = aClass.getGenericInterfaces();
		ParameterizedType enumTrans = null;
		for (Type type : interfaceTypes) {
			if (type instanceof ParameterizedType &&
					((ParameterizedType) type).getRawType() == EnumTrans.class) {
				enumTrans = (ParameterizedType) type;
				break;
			}
		}
		try {
			//获取Trans接口的Type
			if (Objects.nonNull(enumTrans)) {
				// 获取 Trans 接口的泛型参数 P 的 Class 对象
				return (Class<?>) enumTrans.getActualTypeArguments()[0];
			}
		} catch (Exception e) {
			log.error("", e);
		}
		throw new ReflexException("类型处理");
	}
}
